import com.reflect.bean.Car;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test01 {
    //    1.获取class对象多种方式
    @Test
    public void test01() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//        1 类名.class
        Class clazz1 = Car.class;

//        2 对象getClass()
        Class clazz2 = new Car().getClass();

//        3 Class.forName("全路经")
        Class clazz3 = Class.forName("com.reflect.bean.Car");
        System.out.println("反射的对象的路径：" + clazz3);

//        实例化
        Car car1 = (Car) clazz3.getDeclaredConstructor().newInstance();
        Car car2 = (Car) clazz2.getDeclaredConstructor().newInstance();
        Car car3 = (Car) clazz1.getDeclaredConstructor().newInstance();
        System.out.println(car1);
        System.out.println(car2);
        System.out.println(car3);

    }

    @Test
    public void test02() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//        通过反射获取构造函数，和函数的参数数量
//        1 类名.class
        Class clazz = Car.class;
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor + ": :" + constructor.getParameterCount());
        }
//        指定有参数构造创建对象
//        1.构造public
        Constructor c1 = clazz.getConstructor(int.class, String.class, String.class);
        Car car1 = (Car) c1.newInstance(10, "夏利", "红色");
        System.out.println(car1);
        System.out.println(car1.getClass());

    }

    @Test
//  用反射操作属性
    public void test03() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class clazz = Car.class;
        Car car = (Car)clazz.getDeclaredConstructor().newInstance();
//        获取所有public属性
//        Field[] fields = clazz.getFields();
//        获取所有属性（包含私有属性）
        Field[] fields = clazz.getDeclaredFields();
        for(Field field : fields){
            if(field.getName().equals("name")){
//                设置允许访问
                field.setAccessible(true);
                field.set(car,"五菱宏光");
            }
            System.out.println(field.getName());
        }
    }

    @Test
    public void test04() throws InterruptedException {
        Car car = new Car(1,"f","红色");
        Class<? extends Car> clazz = car.getClass();
        for(Method m : clazz.getMethods()) {
            System.out.println(m.getName());
        }
    }
}
